/*
 *所有关于commandlog类的业务代码应在此处编写
*可使用repository.调用常用方法，获取EF/Dapper等信息
*如果需要事务请使用repository.DbContextBeginTransaction
*也可使用DBServerProvider.手动获取数据库相关信息
*用户信息、权限、角色等使用UserContext.Current操作
*commandlogService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter
*/
using VOL.Core.BaseProvider;
using VOL.Core.Extensions.AutofacManager;
using VOL.Entity.DomainModels;
using System.Linq;
using VOL.Core.Utilities;
using System.Linq.Expressions;
using VOL.Core.Extensions;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using VOL.RadarDevice.IRepositories;
using VOL.Core.Enums;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using SqlSugar;
using VOL.Core.DbContext;
using VOL.Entity.DomainModels.Devices.MongoDbModels;
using Newtonsoft.Json;
using System.Collections.Generic;
using AutoMapper.Internal.Mappers;
using AutoMapper;
using VOL.Entity.DomainModels.Devices.Dto;
using VOL.Core.Configuration;
using VOL.Core.ManageUser;
using Microsoft.Extensions.Options;

namespace VOL.RadarDevice.Services
{
    public partial class commandlogService
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly IcommandlogRepository _repository;//访问数据库
        private readonly IdeviceShareRepository _repositorySharp;//访问数据库
        private readonly MongoDbContext _mongoDbContext;
        private readonly IMapper _mapper;

        [ActivatorUtilitiesConstructor]
        public commandlogService(
            IMapper mapper,
            MongoDbContext mongoDbContext,
            IcommandlogRepository dbRepository,
            IdeviceShareRepository repositorySharp,
            IHttpContextAccessor httpContextAccessor
            )
        : base(dbRepository)
        {
            _httpContextAccessor = httpContextAccessor;
            _repository = dbRepository;
            _repositorySharp = repositorySharp;
            _mongoDbContext = mongoDbContext;
            _mapper = mapper;
            //多租户会用到这init代码，其他情况可以不用
            //base.Init(dbRepository);
        }
        //查询
        public override PageGridData<commandlog> GetPageData(PageDataOptions options)
        {
            var deviceNo = "";
            var flag = "";
            DateTime? startTime = null;
            DateTime? endTime = null;

            var listWhere = JsonConvert.DeserializeObject<List<OptionWheres>>(options.Wheres);
            foreach(var item in listWhere)
            {
                if(item.name == "deviceNo")
                    deviceNo = item.value;
                else if(item.name == "flag")
                    flag = item.value;
                else if(item.name == "createTime" && item.displayType== "thanorequal")
                    startTime = DateTime.Parse(item.value);
                else if (item.name == "createTime" && item.displayType == "lessorequal")
                    endTime = DateTime.Parse(item.value);
            }
            PageGridData<commandlog> pageGridData = new PageGridData<commandlog>();
            int pageSize = options.Rows; // 每页显示的数量
            int pageIndex = options.Page; // 当前页码

            IEnumerable<CommandLog> querys2 = null;
            ISugarQueryable<commandlog> querys = null;
            List<commandlog> entitys = null;
            bool isUserMongo = false;
            if (startTime.HasValue && startTime.Value.AddDays(1) > DateTime.Now)
            {
                isUserMongo = true;
                querys2 = _mongoDbContext.CommandLog.WhereIF(!string.IsNullOrEmpty(deviceNo), m => m.deviceNo.Contains(deviceNo))
                   .WhereIF(!string.IsNullOrEmpty(flag), m => m.flag == int.Parse(flag))
                   .WhereIF(startTime.HasValue, m => m.AddTime >= new DateTimeOffset(startTime.Value))
                   .WhereIF(endTime.HasValue, m => m.AddTime <= new DateTimeOffset(endTime.Value));

                var allowIds = AppSetting.QueryAllDeviceUserIds;
                if (!string.IsNullOrWhiteSpace(allowIds))
                {
                    var userId = UserContext.Current.UserId;
                    var strIds = allowIds.Split(',');
                    var ids = Array.ConvertAll(strIds, int.Parse);
                    if (!ids.Contains(userId))
                    {
                        var sharpModels = _repositorySharp.FindAsIQueryable(r => 1 == 1).ToList();
                        List<deviceShare> shares = new List<deviceShare>();
                        foreach (var sharpModel in sharpModels)
                        {
                            var userIds = sharpModel.shareUserIds.Split(",");
                            if (userIds.Contains(userId.ToString()))
                            {
                                shares.Add(sharpModel);
                            }
                        }
                        var deviceNoLIst = shares.Select(r => r.deviceNo).ToList();
                        querys2 = querys2.Where(d => d.CreateID == userId || deviceNoLIst.Contains(d.deviceNo));
                    }
                }

                pageGridData.total = querys2.ToList().Count;
                var dtos = querys2;
                if (options.Order == "desc")
                    dtos = querys2.OrderByDescending(u => u.createTime).Skip((pageIndex - 1) * pageSize).Take(pageSize);
                else
                    dtos = querys2.OrderBy(u => u.createTime).Skip((pageIndex - 1) * pageSize).Take(pageSize);
                var models = dtos.ToList();
                foreach (var model in models)
                {
                    model.createTime = model.AddTime.LocalDateTime;
                }
                entitys = _mapper.Map<List<commandlog>>(models);
            }
            else
            {
                querys = _repository.WhereIF(!string.IsNullOrEmpty(deviceNo), m => m.deviceNo.Contains(deviceNo))
                   .WhereIF(!string.IsNullOrEmpty(flag), m => m.flag == int.Parse(flag))
                   .WhereIF(startTime.HasValue, m => m.createTime >= startTime.Value)
                   .WhereIF(endTime.HasValue, m => m.createTime <= endTime.Value);

                var allowIds = AppSetting.QueryAllDeviceUserIds;
                if (!string.IsNullOrWhiteSpace(allowIds))
                {
                    var userId = UserContext.Current.UserId;
                    var strIds = allowIds.Split(',');
                    var ids = Array.ConvertAll(strIds, int.Parse);
                    if (!ids.Contains(userId))
                    {
                        var sharpModels = _repositorySharp.FindAsIQueryable(r => 1 == 1).ToList();
                        List<deviceShare> shares = new List<deviceShare>();
                        foreach (var sharpModel in sharpModels)
                        {
                            var userIds = sharpModel.shareUserIds.Split(",");
                            if (userIds.Contains(userId.ToString()))
                            {
                                shares.Add(sharpModel);
                            }
                        }
                        var deviceNoLIst = shares.Select(r => r.deviceNo).ToList();
                        querys = querys.Where(d => d.CreateID == userId || deviceNoLIst.Contains(d.deviceNo));
                    }
                }

                pageGridData.total = querys.ToList().Count;
                var dtos = querys;
                if (options.Order == "desc")
                    dtos = querys.OrderByDescending(u => u.createTime).Skip((pageIndex - 1) * pageSize).Take(pageSize);
                else
                    dtos = querys.OrderBy(u => u.createTime).Skip((pageIndex - 1) * pageSize).Take(pageSize);
                var models = dtos.ToList();
                entitys = _mapper.Map<List<commandlog>>(models);
            }
            pageGridData.rows = entitys;
            GetPageDataOnExecuted?.Invoke(pageGridData);
            return pageGridData;
        }
        /// <summary>
        /// 导出处理
        /// </summary>
        /// <param name="pageData"></param>
        /// <returns></returns>
        public override WebResponseContent Export(PageDataOptions pageData)
        {
            var deviceNo = "";
            var flag = "";
            DateTime? startTime = null;
            DateTime? endTime = null;

            var listWhere = JsonConvert.DeserializeObject<List<OptionWheres>>(pageData.Wheres);
            foreach (var item in listWhere)
            {
                if (item.name == "deviceNo")
                    deviceNo = item.value;
                else if (item.name == "flag")
                    flag = item.value;
                else if (item.name == "createTime" && item.displayType == "thanorequal")
                    startTime = DateTime.Parse(item.value);
                else if (item.name == "createTime" && item.displayType == "lessorequal")
                    endTime = DateTime.Parse(item.value);
            }

            IEnumerable<CommandLog> querys2 = null;
            ISugarQueryable<commandlog> querys = null;
            List<commandlog> entitys = null;
            bool isUserMongo = false;

            if (startTime.HasValue && startTime.Value.AddDays(1) > DateTime.Now)
            {
                isUserMongo = true;
                querys2 = _mongoDbContext.CommandLog.WhereIF(!string.IsNullOrEmpty(deviceNo), m => m.deviceNo.Contains(deviceNo))
                   .WhereIF(!string.IsNullOrEmpty(flag), m => m.flag == int.Parse(flag))
                   .WhereIF(startTime.HasValue, m => m.AddTime >= new DateTimeOffset(startTime.Value))
                   .WhereIF(endTime.HasValue, m => m.AddTime <= new DateTimeOffset(endTime.Value));

                var allowIds = AppSetting.QueryAllDeviceUserIds;
                if (!string.IsNullOrWhiteSpace(allowIds))
                {
                    var userId = UserContext.Current.UserId;
                    var strIds = allowIds.Split(',');
                    var ids = Array.ConvertAll(strIds, int.Parse);
                    if (!ids.Contains(userId))
                    {
                        var sharpModels = _repositorySharp.FindAsIQueryable(r => 1 == 1).ToList();
                        List<deviceShare> shares = new List<deviceShare>();
                        foreach (var sharpModel in sharpModels)
                        {
                            var userIds = sharpModel.shareUserIds.Split(",");
                            if (userIds.Contains(userId.ToString()))
                            {
                                shares.Add(sharpModel);
                            }
                        }
                        var deviceNoLIst = shares.Select(r => r.deviceNo).ToList();
                        querys2 = querys2.Where(d => d.CreateID == userId || deviceNoLIst.Contains(d.deviceNo));
                    }
                }
                var dtos = querys2;
                if (pageData.Order == "asc")
                    dtos = querys2.OrderBy(u => u.createTime);
                else
                    dtos = querys2.OrderByDescending(u => u.createTime);
                var list = dtos.ToList();
                foreach (var model in list)
                {
                    model.createTime = model.AddTime.LocalDateTime;
                }
                entitys = _mapper.Map<List<commandlog>>(list);
            }
            else
            {
                querys = _repository.WhereIF(!string.IsNullOrEmpty(deviceNo), m => m.deviceNo.Contains(deviceNo))
               .WhereIF(!string.IsNullOrEmpty(flag), m => m.flag == int.Parse(flag))
               .WhereIF(startTime.HasValue, m => m.createTime >= startTime.Value)
               .WhereIF(endTime.HasValue, m => m.createTime <= endTime.Value);

                var allowIds = AppSetting.QueryAllDeviceUserIds;
                if (!string.IsNullOrWhiteSpace(allowIds))
                {
                    var userId = UserContext.Current.UserId;
                    var strIds = allowIds.Split(',');
                    var ids = Array.ConvertAll(strIds, int.Parse);
                    if (!ids.Contains(userId))
                    {
                        var sharpModels = _repositorySharp.FindAsIQueryable(r => 1 == 1).ToList();
                        List<deviceShare> shares = new List<deviceShare>();
                        foreach (var sharpModel in sharpModels)
                        {
                            var userIds = sharpModel.shareUserIds.Split(",");
                            if (userIds.Contains(userId.ToString()))
                            {
                                shares.Add(sharpModel);
                            }
                        }
                        var deviceNoLIst = shares.Select(r => r.deviceNo).ToList();
                        querys = querys.Where(d => d.CreateID == userId || deviceNoLIst.Contains(d.deviceNo));
                    }
                }
                var dtos = querys;
                if (pageData.Order == "asc")
                    dtos = querys.OrderBy(u => u.createTime);
                else
                    dtos = querys.OrderByDescending(u => u.createTime);
                entitys = dtos.ToList();
            }
            return base.MyExport(entitys);
        }
        public static DateTime BeijingToUtc(DateTime beijingTime)
        {
            TimeZoneInfo chinaZone = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time");
            return TimeZoneInfo.ConvertTimeToUtc(beijingTime, chinaZone);
        }
    }
}
